# language: zh-CN
# 需求ID: REQ-004
# SRS需求: 7.1 声明式验证规则
# Feature ID: Epic 7.1
# 用户故事: US-021, US-022, US-023
功能: 声明式校验
  作为领域专家
  我希望能在YAML DSL v2.0中声明字段验证规则
  以便确保数据质量并支持跨字段验证和类型别名

  背景:
    假设我是一个领域专家
    并且我需要定义数据验证规则
    并且我希望规则能自动执行
    并且我使用DSL v2.0的跨字段验证和类型别名特性

  # US-021: 作为领域专家，我希望能在DSL中声明字段验证规则
  场景: 基础字段验证规则支持DSL v2.0特性
    假设我定义了包含验证规则的实体:
      """
      @fixtures/entities/user-dsl.yml
      """
    当我尝试创建用户时
    那么系统应该验证所有字段规则
    并且应该在验证失败时返回详细错误信息
    并且应该支持多个验证规则的组合
    并且应该正确处理类型别名的验证规则
    并且应该执行跨字段验证约束
    并且应该根据参数化模板动态验证字段

  场景: 验证规则在创建时执行支持DSL v2.0特性
    假设我尝试创建一个无效用户:
      """
      {
        "name": "A",                    // 太短
        "email": "invalid-email",       // 格式错误
        "age": -5,                      // 小于最小值
        "password": "123",              // 不符合复杂度要求
        "confirmPassword": "456"        // 与密码不匹配（跨字段验证）
      }
      """
    当我提交创建请求时
    那么系统应该返回验证错误:
      """
      {
        "errors": [
          {
            "field": "name",
            "code": "MIN_LENGTH",
            "message": "姓名长度不能少于2个字符"
          },
          {
            "field": "email",
            "code": "INVALID_EMAIL",
            "message": "邮箱格式不正确"
          },
          {
            "field": "age",
            "code": "MIN_VALUE",
            "message": "年龄不能小于0"
          },
          {
            "field": "password",
            "code": "PATTERN_MISMATCH",
            "message": "密码必须包含大小写字母和数字"
          }
        ]
      }
      """
    并且应该阻止数据保存

  场景: 验证规则在更新时执行
    假设我有一个现有用户
    当我尝试更新用户信息:
      """
      {
        "email": "duplicate@example.com"  // 已存在的邮箱
      }
      """
    那么系统应该验证唯一性约束
    并且应该返回唯一性冲突错误
    并且应该阻止更新操作
    并且应该保持原有数据不变

  # US-022: 作为领域专家，我希望能定义跨字段验证规则
  场景: 跨字段复杂验证
    假设我定义了跨字段验证规则:
      """
      # User Domain Model with Cross-field Validation
      name: User
      version: 1.0.0
      
      entity:
        name: User
        table: users
        
        fields:
          birthDate:
            type: date
            required: true
          
          age:
            type: number
            required: true
          
          startDate:
            type: date
            required: true
          
          endDate:
            type: date
            optional: true
        
        validations:
          - name: age_matches_birth_date
            message: 'age should match birth date'
            rule: 'age === calculateAge(birthDate)'
          
          - name: end_date_after_start
            message: 'end date must be after start date'
            rule: 'endDate > startDate'
            condition: 'endDate != null'
      """
    当我创建用户时
    那么系统应该验证年龄与出生日期的一致性
    并且应该验证结束日期晚于开始日期
    并且应该在跨字段验证失败时返回相应错误

  # US-023: 作为领域专家，我希望能定义条件验证规则
  场景: 条件验证规则
    假设我定义了条件验证:
      """
      # User Domain Model with Conditional Validation
      name: User
      version: 1.0.0
      
      entity:
        name: User
        table: users
        
        fields:
          type:
            type: enum
            values: ['individual', 'company']
            required: true
          
          firstName:
            type: string
            requiredIf:
              field: type
              value: individual
          
          lastName:
            type: string
            requiredIf:
              field: type
              value: individual
          
          companyName:
            type: string
            requiredIf:
              field: type
              value: company
          
          taxId:
            type: string
            requiredIf:
              field: type
              value: company
      """
    当我创建个人用户时
    那么firstName和lastName应该是必填的
    并且companyName和taxId应该是可选的
    当我创建企业用户时
    那么companyName和taxId应该是必填的
    并且firstName和lastName应该是可选的

  场景: 自定义验证器
    假设我需要自定义业务验证逻辑:
      """
      # User Domain Model with Custom Validator
      name: User
      version: 1.0.0
      
      entity:
        name: User
        table: users
        
        fields:
          email:
            type: string
            required: true
            format: email
          
          domain:
            type: string
            required: true
        
        customValidators:
          - name: email_domain_match
            function: |
              function emailDomainMatch(user) {
                const emailDomain = user.email.split('@')[1];
                return emailDomain === user.domain;
              }
            message: 'Email domain must match the specified domain'
      """
    当我创建用户时
    那么系统应该执行自定义验证器
    并且应该验证邮箱域名与指定域名匹配
    并且应该在验证失败时返回自定义错误消息

  场景: 异步验证支持
    假设我需要进行异步验证（如检查外部API）:
      """
      # User Domain Model with Async Validation
      name: User
      version: 1.0.0
      
      entity:
        name: User
        table: users
        
        fields:
          email:
            type: string
            required: true
            format: email
            asyncValidation:
              type: unique
              service: external_system
              timeout: 5000
          
          licenseNumber:
            type: string
            asyncValidation:
              type: custom
              service: license_verification_service
              timeout: 10000
              cache: true
              cacheTtl: 3600
      """
    当我创建用户时
    那么系统应该执行异步验证
    并且应该等待外部验证完成
    并且应该处理外部服务的超时和错误
    并且应该缓存验证结果避免重复调用

  场景: 验证规则的国际化
    假设应用需要支持多语言
    当验证失败时
    那么错误消息应该根据用户语言环境显示
    并且应该支持错误消息的参数化
    并且应该提供默认的多语言错误消息
    并且应该允许自定义错误消息模板